package grpc

import (
	"go-main/library/ecode"
	"go-main/library/net/trace"
	"io"

	context "golang.org/x/net/context"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

var (
	tagCode  = "grpc.code"
	tagEcode = "ecode"
)

// grpc_trace.FinishWithError applies finish option and a tag with gRPC status code, disregarding OK, EOF and Canceled errors.
func FinishWithError(t trace.Trace, e *error) {
	if e == nil {
		t.Finish(e)
		return
	}
	err := *e

	// grpc error 判断标准
	// ecode != 0 && grpc.code !=0 && err != io.EOF && err != context.Canceled
	// TODO: implement non error code => cfg.nonErrorCodes[errcode]

	// error 情况下，会有tag grpc.code, ecode。正常情况下，没有上述两个tag
	ecode := ecode.Cause(err)
	errcode := status.Code(err)
	if err == io.EOF || err == context.Canceled {
		err = nil
	}
	if ecode.Code() != 0 {
		t.SetTag(
			trace.Tag{
				Key:   tagEcode,
				Value: ecode.Code(),
			},
		)
	} else {
		err = nil
	}

	// TODO: implement non error code => cfg.nonErrorCodes[errcode]
	if errcode != codes.OK {
		t.SetTag(
			trace.Tag{
				Key:   tagCode,
				Value: errcode.String(),
			},
		)
	} else {
		err = nil
	}

	t.Finish(&err)
}
